package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.OrdersDto;
import com.itheima.reggie.entity.OrderDetail;
import com.itheima.reggie.entity.Orders;
import com.itheima.reggie.entity.ShoppingCart;
import com.itheima.reggie.entity.User;
import com.itheima.reggie.service.OrderDetailService;
import com.itheima.reggie.service.OrderService;
import com.itheima.reggie.service.ShoppingCartService;
import com.itheima.reggie.service.UserService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 订单
 */
@Slf4j
@RestController
@RequestMapping("/order")
@Api(tags = "订单相关接口")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private UserService userService;

    @Autowired
    private ShoppingCartService shoppingCartService;

    /**
     * 用户下单
     *
     * @param orders
     * @return
     */
    @PostMapping("/submit")
    public R<String> submit(@RequestBody Orders orders) {
        log.info("订单数据：{}", orders);
        orderService.submit(orders);
        return R.success("下单成功");
    }

    /*
     * 只有order是不够的
     * 要把orderdetail加上一起传到orderdto里面*/
    //然而事实证明并不需要...
    //诶,需要,还有个:个数没有显示,怎么实现?
    //用传递类

    /**
     * 前端历史订单显示
     *
     * @param page
     * @param pageSize
     * @return
     */
    @GetMapping("/userPage")

    public R<Page<OrdersDto>> showOrdersFront(Integer page,
                                              Integer pageSize) {
        Long userId = BaseContext.getCurrentId();//获取当前用户id
        Page<Orders> ordersPage = new Page<>(page, pageSize);
//        Page<OrderDetail> orderDetailPage = new Page<>(page, pageSize);
        Page<OrdersDto> ordersDtoPage = new Page<>();//新建一个传递对象的page对象

        LambdaQueryWrapper<Orders> lqw1 = new LambdaQueryWrapper<>();
        lqw1.eq(userId != null, Orders::getUserId, userId);
        lqw1.orderByDesc(Orders::getCheckoutTime);
        orderService.page(ordersPage, lqw1);
        List<Orders> ordersList = ordersPage.getRecords();//获取订单的集合

//        把orders中的数据先赋值到传递对象上
        List<OrdersDto> ordersDtos = ordersList.stream().map(orders -> {
            OrdersDto ordersDto = new OrdersDto();
            BeanUtils.copyProperties(orders, ordersDto);//把基本的信息复制到传递对象上
            Long ordersId = orders.getId();
            LambdaQueryWrapper<OrderDetail> qw = new LambdaQueryWrapper<>();
            qw.eq(ordersId != null, OrderDetail::getOrderId, ordersId);
            List<OrderDetail> details = orderDetailService.list(qw);//用订单id找到对应的订单细节
            ordersDto.setOrderDetails(details);//把订单细节也写到传递对象上去
            return ordersDto;
        }).collect(Collectors.toList());
        //找到订单数据的id 用id找到对应的订单细节对象 也赋值到传递类中
        ordersDtoPage.setRecords(ordersDtos);//把所有的信息都传递过去
        return R.success(ordersDtoPage);
    }

    /**
     * 后端显示订单的分页查询
     *
     * @param page
     * @param pageSize
     * @param number
     * @param beginTime
     * @param endTime
     * @return
     */

    //这边userName 是order中没有的,所以也要借助传递类来实现功能
    @GetMapping("/page")
    public R<Page<OrdersDto>> showOrdersBackend(Integer page,
                                                Integer pageSize,
                                                Long number,
                                                String beginTime,
                                                String endTime
    ) {
        Page<Orders> ordersPage = new Page<>(page, pageSize);
        Page<OrdersDto> ordersDtopage = new Page<>();

        LambdaQueryWrapper<Orders> qw = new LambdaQueryWrapper<>();
        qw.eq(number != null, Orders::getNumber, number);
        qw.orderByDesc(Orders::getOrderTime);
        qw.gt(beginTime != null, Orders::getOrderTime, beginTime);
        qw.lt(beginTime != null, Orders::getOrderTime, endTime);
        orderService.page(ordersPage, qw);
        BeanUtils.copyProperties(ordersPage, ordersDtopage, "records");//先把基础功能给拷贝过去
        List<Orders> records = ordersPage.getRecords();
        List<OrdersDto> ordersDtoList = records.stream().map(new Function<Orders, OrdersDto>() {
            @Override
            public OrdersDto apply(Orders orders) {
                OrdersDto ordersDto = new OrdersDto();
                BeanUtils.copyProperties(orders, ordersDto);
                Long userId = orders.getUserId();
                User user = userService.getById(userId);
                String userName = user.getName();
                ordersDto.setUserName(userName);
                return ordersDto;
            }
        }).collect(Collectors.toList());
        ordersDtopage.setRecords(ordersDtoList);

        return R.success(ordersDtopage);

    }

    /**
     * 派送
     *
     * @return
     */
    @PutMapping
    public R<Orders> send(@RequestBody Orders orders) {
        Integer status = orders.getStatus();
        if (status == 2) {
            orders.setStatus(3);
            orderService.updateById(orders);
            return R.success(orders);
        } else if (status == 3) {
            orders.setStatus(4);
            orderService.updateById(orders);
            return R.success(orders);
        }
        return R.error("派送失败");

    }

        //    再来一单
        //    前端传过来的是什么
        //    前端需要什么?
    @PostMapping("/again")
    public R<String> orderAgain(@RequestBody Map<String, Long> map) {
        //先按照要求获取上一单的信息
        Long id = map.get("id");//获取订单的id
        //获取该订单对应的所有的订单明细表
        LambdaQueryWrapper<OrderDetail> orderDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderDetailLambdaQueryWrapper.eq(OrderDetail::getOrderId, id);
        List<OrderDetail> orderDetailList = orderDetailService.list(orderDetailLambdaQueryWrapper);
        //通过用户id把原来的购物车给清空;
        LambdaQueryWrapper<ShoppingCart> shoppingCartLambdaQueryWrapper = new LambdaQueryWrapper<>();
        Long currentId = BaseContext.getCurrentId();
        shoppingCartLambdaQueryWrapper.eq(ShoppingCart::getUserId, currentId);
        shoppingCartService.remove(shoppingCartLambdaQueryWrapper);
        //把从order表中和order_details表中获取到的数据赋值给这个购物车对象
        List<ShoppingCart> shoppingCarts = orderDetailList.stream().map(orderDetail -> {
            ShoppingCart shoppingCart = new ShoppingCart();
            shoppingCart.setUserId(currentId);
            shoppingCart.setImage(orderDetail.getImage());
            Long dishId = orderDetail.getDishId();
            Long setmealId = orderDetail.getSetmealId();
            if (dishId != null) {
//如果是菜品那就添加菜品的查询条件
                shoppingCart.setDishId(dishId);
            } else {
//添加到购物车的是套餐
                shoppingCart.setSetmealId(setmealId);
            }
            shoppingCart.setName(orderDetail.getName());
            shoppingCart.setDishFlavor(orderDetail.getDishFlavor());
            shoppingCart.setNumber(orderDetail.getNumber());
            shoppingCart.setAmount(orderDetail.getAmount());
            shoppingCart.setCreateTime(LocalDateTime.now());
            return shoppingCart;
        }).collect(Collectors.toList());

        shoppingCartService.saveBatch(shoppingCarts);

        //把携带数据的购物车批量插入购物车表 这个批量保存的方法要使用熟练！！！

        return R.success("操作成功");
    }


//    客户端点击再来一单

//    /**
//     * 前端点击再来一单是直接跳转到购物车的;所以为了避免数据有问题;再跳转之前我们需要把购物车的数据给清除
//     * ①通过orderId获取订单明细
//     * ②把订单明细的数据的数据塞到购物车表中;不过在此之前要先把购物车表中的数据给清除(清除的是当前登录用户的购物车表中的数据);
//     * 不然就会导致再来一单的数据有问题；
//     * (这样可能会影响用户体验;但是对于外卖来说;用户体验的影响不是很大;电商项目就不能这么干了)
//     */
//    @PostMapping("/again")
//    public R<String> againSubmit(@RequestBody Map<String, String> map) {
//        String ids = map.get("id");
//        long id = Long.parseLong(ids);
//        LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(OrderDetail::getOrderId, id);
////获取该订单对应的所有的订单明细表
//        List<OrderDetail> orderDetailList = orderDetailService.list(queryWrapper);
////通过用户id把原来的购物车给清空;
//        shoppingCartService.remove(null);
////获取用户id
//        Long userId = BaseContext.getCurrentId();
//        List<ShoppingCart> shoppingCartList = orderDetailList.stream().map((item) -> {
////把从order表中和order_details表中获取到的数据赋值给这个购物车对象
//            ShoppingCart shoppingCart = new ShoppingCart();
//            shoppingCart.setUserId(userId);
//            shoppingCart.setImage(item.getImage());
//            Long dishId = item.getDishId();
//            Long setmealId = item.getSetmealId();
//            if (dishId != null) {
////如果是菜品那就添加菜品的查询条件
//                shoppingCart.setDishId(dishId);
//            } else {
////添加到购物车的是套餐
//                shoppingCart.setSetmealId(setmealId);
//            }
//            shoppingCart.setName(item.getName());
//            shoppingCart.setDishFlavor(item.getDishFlavor());
//            shoppingCart.setNumber(item.getNumber());
//            shoppingCart.setAmount(item.getAmount());
//            shoppingCart.setCreateTime(LocalDateTime.now());
//            return shoppingCart;
//        }).collect(Collectors.toList());
////把携带数据的购物车批量插入购物车表 这个批量保存的方法要使用熟练！！！
//        shoppingCartService.saveBatch(shoppingCartList);
//        return R.success("操作成功");
//    }
}
